#pragma once

#include "Reactor.hpp"
#include "Channel.hpp"
#include "Socket.hpp"
#include "InetAddr.hpp"
#include "Connection.hpp"
#include "Log.hpp"

class Listener:public Connection{
public:
	Listener(uint16_t port):_port(port), _listensockfd(std::make_unique<TcpSocket>()){
		_listensockfd->BulidTcpSocketMethod(_port);
		SetEvents(EPOLLIN | EPOLLET);
		SetNoBlock(_listensockfd->GetFd());
	}

	void Recever() override{
		InetAddr client;
		while(true){
			int acpt_ret = _listensockfd->Accept(&client);
			if(acpt_ret < 0){
				if(errno == EAGAIN || errno == EWOULDBLOCK){
					// 数据未准备好
					continue;
				}
				else if(errno == EINTR)
					continue;
				else{
					LOG(LogLevel::ERROR) << "accept error";
					break;
				}
			}
			else if(acpt_ret == 0){
				break;
			}
			else{
				// 完成新连接从监听层到IO层的封装
				auto conn = std::make_shared<Channel>(acpt_ret, client);
				// 设置事件
				conn->SetEvents(EPOLLIN | EPOLLET);
				// 执行任务函数
				conn->RegisterHandler(_handler);
				// 将 Channel 移交 Reactor 管理
				GetOwner()->AddConnection(conn);
				LOG(LogLevel::INFO) << "new client connected from " << client.StringAddr();
			}
		}
	}

	void Sender() override{
		LOG(LogLevel::ERROR) << "listener has no sender";
	}

	void Excepter() override{
		LOG(LogLevel::ERROR) << "listener has no excepter";
	}

	int GetSockFd() override{
		return _listensockfd->GetFd();
	}

private:
	uint16_t _port;
	std::unique_ptr<TcpSocket> _listensockfd;
};